#include "lxz_config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lxz_types.h"
#include "os_port.h"
#include "lxz_runlog.h"
#include "lxz_debug.h"
#include "lxz_ring.h"
#include "lxz_string.h"
#include "lxz_dstring.h"
#include "lxz_atc_req.h"
#include "lxz_calc_cmd.h"
#include "lxz_dbg_vmem.h"

static sint32 lxzat_plus_dccalc_init(void * pctxt);
static sint32 lxzat_plus_dcadd_req(void * pctxt);
static sint32 lxzat_plus_dcdel_req(void * pctxt);
static sint32 lxzat_plus_dcmul_req(void * pctxt);
static sint32 lxzat_plus_dcdiv_req(void * pctxt);
static sint32 lxzat_plus_dccalc_resp(void * pctxt);
static sint32 lxzat_plus_dccalc_reset(void * pctxt);

static sint32 lxzat_plus_dcstradd_init(void * pctxt);
static sint32 lxzat_plus_dcstradd_req(void * pctxt);
static sint32 lxzat_plus_dcstradd_resp(void * pctxt);
static sint32 lxzat_plus_dcstradd_reset(void * pctxt);
static sint32 lxzat_plus_dcstrdel_init(void * pctxt);
static sint32 lxzat_plus_dcstrdel_req(void * pctxt);
static sint32 lxzat_plus_dcstrdel_resp(void * pctxt);
static sint32 lxzat_plus_dcstrdel_reset(void * pctxt);

/*
 *  Description:
 *    A structure for saving parameters and result.
 *  Note: NONE
 */
typedef struct _lxzat_resp_calc_t
{
    sint32 it_param1; /* the 1st parameter */
    sint32 it_param2; /* the 2nd parameter */
    sint32 it_result; /* the result */
} lxzat_resp_calc_t;

/*
 *  Description:
 *    A structure for saving parameters and result.
 *  Note: NONE
 */
typedef struct _lxzat_resp_strcalc_t
{
    lxz_dstring_t * pt_param1; /* the 1st parameter */
    lxz_dstring_t * pt_param2; /* the 2nd parameter */
    lxz_dstring_t * pt_result; /* the result */
} lxzat_resp_strcalc_t;

/*
 *  Description:
 *    A caplets for hiding concrete implementation.
 *  Note: 
 *    Please do not change any part of current piece when you unsure.
 */
const lxzat_info_t lai_plus_dcadd =
{
    LXZAT_TYPE_RANGE_LOCAL|LXZAT_TYPE_STRING_EXTEND,
    "+DCADD",
    lxzat_plus_dccalc_init,
    lxzat_plus_dcadd_req,
    lxzat_plus_dccalc_resp,
    lxzat_plus_dccalc_reset
};

/*
 *  Description:
 *    A caplets for hiding concrete implementation.
 *  Note: 
 *    Please do not change any part of current piece when you unsure.
 */
const lxzat_info_t lai_plus_dcdel =
{
    LXZAT_TYPE_RANGE_LOCAL|LXZAT_TYPE_STRING_EXTEND,
    "+DCDEL", 
    lxzat_plus_dccalc_init,
    lxzat_plus_dcdel_req,
    lxzat_plus_dccalc_resp,
    lxzat_plus_dccalc_reset  
};

/*
 *  Description:
 *    A caplets for hiding concrete implementation.
 *  Note: 
 *    Please do not change any part of current piece when you unsure.
 */
const lxzat_info_t lai_plus_dcmul =
{
    LXZAT_TYPE_RANGE_LOCAL|LXZAT_TYPE_STRING_EXTEND,
    "+DCMUL", 
    lxzat_plus_dccalc_init,
    lxzat_plus_dcmul_req,
    lxzat_plus_dccalc_resp,
    lxzat_plus_dccalc_reset  
};

/*
 *  Description:
 *    A caplets for hiding concrete implementation.
 *  Note: 
 *    Please do not change any part of current piece when you unsure.
 */
const lxzat_info_t lai_plus_dcdiv =
{
    LXZAT_TYPE_RANGE_LOCAL|LXZAT_TYPE_STRING_EXTEND,
    "+DCDIV", 
    lxzat_plus_dccalc_init,
    lxzat_plus_dcdiv_req,
    lxzat_plus_dccalc_resp,
    lxzat_plus_dccalc_reset  
};

/*
 *  Description:
 *    A caplets for hiding concrete implementation.
 *  Note: 
 *    Please do not change any part of current piece when you unsure.
 */
const lxzat_info_t lai_plus_dcstradd =
{
    LXZAT_TYPE_RANGE_LOCAL|LXZAT_TYPE_STRING_EXTEND,
    "+DCSTRADD", 
    lxzat_plus_dcstradd_init,
    lxzat_plus_dcstradd_req,
    lxzat_plus_dcstradd_resp,
    lxzat_plus_dcstradd_reset
};

/*
 *  Description:
 *    A caplets for hiding concrete implementation.
 *  Note: 
 *    Please do not change any part of current piece when you unsure.
 */
const lxzat_info_t lai_plus_dcstrdel =
{
    LXZAT_TYPE_RANGE_LOCAL|LXZAT_TYPE_STRING_EXTEND,
    "+DCSTRDEL", 
    lxzat_plus_dcstrdel_init,
    lxzat_plus_dcstrdel_req,
    lxzat_plus_dcstrdel_resp,
    lxzat_plus_dcstrdel_reset
};

/*
 *  Description:
 *    The initialize handler of "AT+DCADD,AT+DCDEL,AT+DCMUL,AT+DCDIV".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dccalc_init(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_ERR_MEM_NOT_ENOUGH;
    
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;
    lxzat_resp_calc_t * p_calc_resp = NULL;

    if (p_lxzat_ctxt != NULL)
    {
        p_calc_resp = (lxzat_resp_calc_t *)malloc(sizeof(lxzat_resp_calc_t));
        if (p_calc_resp != NULL)
        {
            memset(p_calc_resp, 0, sizeof(lxzat_resp_calc_t));
            p_lxzat_ctxt->pt_rsp_data = p_calc_resp;

            e_err_code = E_LEC_OK;
        }
    }
    
    return e_err_code;
}

/*
 *  Description:
 *    The request handler of "AT+DCADD".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dcadd_req(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_OK;

    sint32 i_req_type = LXZAT_REQ_TYPE_ERR;
    lxzat_req_t * p_cur_req = NULL;
    lxzat_spcfg_t * p_cur_spcfg = NULL;
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;

    if (p_lxzat_ctxt == NULL)
    {
        OS_DBG_LOG(("lxzat_plus_dcadd_req,p_lxzat_ctxt is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    p_cur_req = p_lxzat_ctxt->pt_req_data;
    p_cur_spcfg = lxzat_spcomm_f_get(p_lxzat_ctxt->it_vsp_id);
    if ((p_cur_req == NULL) || (p_cur_spcfg == NULL))
    {
        OS_DBG_LOG(("lxzat_plus_dcadd_req,p_cur_req or p_cur_spcfg is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    i_req_type = p_cur_req->it_req_type;
    switch (i_req_type)
    {
    case LXZAT_REQ_TYPE_SET:
        {
            lxzat_resp_calc_t * p_calc_resp = NULL;
            
            if (PARAM1_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_NUMERIC)
            {
                return E_LEC_ERR_P_TYPE;
            }
            
            if (PARAM2_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_NUMERIC)
            {
                return E_LEC_ERR_P_TYPE;
            }

            p_calc_resp = p_lxzat_ctxt->pt_rsp_data;
            p_calc_resp->it_param1 = PARAM1(p_cur_req).it_number;
            p_calc_resp->it_param2 = PARAM2(p_cur_req).it_number;
            p_calc_resp->it_result = p_calc_resp->it_param1 + p_calc_resp->it_param2;
            break;
        }
    case LXZAT_REQ_TYPE_TEST:
        {
            e_err_code = E_LEC_OK;
            break;
        }
    default:
        {
            e_err_code = E_LEC_ERR_UNSUPPORTED;
            break;
        }
    }

    return e_err_code;
}

/*
 *  Description:
 *    The request handler of "AT+DCDEL".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dcdel_req(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_OK;

    sint32 i_req_type = LXZAT_REQ_TYPE_ERR;
    lxzat_req_t * p_cur_req = NULL;
    lxzat_spcfg_t * p_cur_spcfg = NULL;
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;

    if (p_lxzat_ctxt == NULL)
    {
        OS_DBG_LOG(("lxzat_plus_dcdel_req,p_lxzat_ctxt is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    p_cur_req = p_lxzat_ctxt->pt_req_data;
    p_cur_spcfg = lxzat_spcomm_f_get(p_lxzat_ctxt->it_vsp_id);
    if ((p_cur_req == NULL) || (p_cur_spcfg == NULL))
    {
        OS_DBG_LOG(("lxzat_plus_dcdel_req,p_cur_req or p_cur_spcfg is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    i_req_type = p_cur_req->it_req_type;
    switch (i_req_type)
    {
    case LXZAT_REQ_TYPE_SET:
        {
            lxzat_resp_calc_t * p_calc_resp = NULL;
            
            if (PARAM1_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_NUMERIC)
            {
                return E_LEC_ERR_P_TYPE;
            }
            
            if (PARAM2_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_NUMERIC)
            {
                return E_LEC_ERR_P_TYPE;
            }
            
            p_calc_resp = p_lxzat_ctxt->pt_rsp_data;
            p_calc_resp->it_param1 = PARAM1(p_cur_req).it_number;
            p_calc_resp->it_param2 = PARAM2(p_cur_req).it_number;
            p_calc_resp->it_result = p_calc_resp->it_param1 - p_calc_resp->it_param2;
            break;
        }
    case LXZAT_REQ_TYPE_TEST:
        {
            e_err_code = E_LEC_OK;
            break;
        }
    default:
        {
            e_err_code = E_LEC_ERR_UNSUPPORTED;
            break;
        }
    }

    return e_err_code;
}

/*
 *  Description:
 *    The request handler of "AT+DCMUL".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dcmul_req(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_OK;

    sint32 i_req_type = LXZAT_REQ_TYPE_ERR;
    lxzat_req_t * p_cur_req = NULL;
    lxzat_spcfg_t * p_cur_spcfg = NULL;
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;

    if (p_lxzat_ctxt == NULL)
    {
        OS_DBG_LOG(("lxzat_plus_dcmul_req,p_lxzat_ctxt is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    p_cur_req = p_lxzat_ctxt->pt_req_data;
    p_cur_spcfg = lxzat_spcomm_f_get(p_lxzat_ctxt->it_vsp_id);
    if ((p_cur_req == NULL) || (p_cur_spcfg == NULL))
    {
        OS_DBG_LOG(("lxzat_plus_dcmul_req,p_cur_req or p_cur_spcfg is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    i_req_type = p_cur_req->it_req_type;
    switch (i_req_type)
    {
    case LXZAT_REQ_TYPE_SET:
        {
            lxzat_resp_calc_t * p_calc_resp = NULL;
            
            if (PARAM1_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_NUMERIC)
            {
                return E_LEC_ERR_P_TYPE;
            }
            
            if (PARAM2_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_NUMERIC)
            {
                return E_LEC_ERR_P_TYPE;
            }
            
            p_calc_resp = p_lxzat_ctxt->pt_rsp_data;
            p_calc_resp->it_param1 = PARAM1(p_cur_req).it_number;
            p_calc_resp->it_param2 = PARAM2(p_cur_req).it_number;
            p_calc_resp->it_result = p_calc_resp->it_param1 * p_calc_resp->it_param2;
            break;
        }
    case LXZAT_REQ_TYPE_TEST:
        {
            e_err_code = E_LEC_OK;
            break;
        }
    default:
        {
            e_err_code = E_LEC_ERR_UNSUPPORTED;
            break;
        }
    }

    return e_err_code;
}

/*
 *  Description:
 *    The request handler of "AT+DCDIV".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dcdiv_req(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_OK;

    sint32 i_req_type = LXZAT_REQ_TYPE_ERR;
    lxzat_req_t * p_cur_req = NULL;
    lxzat_spcfg_t * p_cur_spcfg = NULL;
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;

    if (p_lxzat_ctxt == NULL)
    {
        OS_DBG_LOG(("lxzat_plus_dcdiv_req,p_lxzat_ctxt is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    p_cur_req = p_lxzat_ctxt->pt_req_data;
    p_cur_spcfg = lxzat_spcomm_f_get(p_lxzat_ctxt->it_vsp_id);
    if ((p_cur_req == NULL) || (p_cur_spcfg == NULL))
    {
        OS_DBG_LOG(("lxzat_plus_dcdiv_req,p_cur_req or p_cur_spcfg is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    i_req_type = p_cur_req->it_req_type;
    switch (i_req_type)
    {
    case LXZAT_REQ_TYPE_SET:
        {
            lxzat_resp_calc_t * p_calc_resp = NULL;
            
            if (PARAM1_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_NUMERIC)
            {
                return E_LEC_ERR_P_TYPE;
            }

            if (PARAM2_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_NUMERIC)
            {
                return E_LEC_ERR_P_TYPE;
            }

            p_calc_resp = p_lxzat_ctxt->pt_rsp_data;
            p_calc_resp->it_param1 = PARAM1(p_cur_req).it_number;
            p_calc_resp->it_param2 = PARAM2(p_cur_req).it_number;
            p_calc_resp->it_result = p_calc_resp->it_param1 / p_calc_resp->it_param2;
            break;
        }
    case LXZAT_REQ_TYPE_TEST:
        {
            e_err_code = E_LEC_OK;
            break;
        }
    default:
        {
            e_err_code = E_LEC_ERR_UNSUPPORTED;
            break;
        }
    }

    return e_err_code;
}

/*
 *  Description:
 *    The response handler of "AT+DCADD,AT+DCDEL,AT+DCMUL,AT+DCDIV".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dccalc_resp(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_OK;

    sint32 i_req_type = LXZAT_REQ_TYPE_ERR;
    lxzat_req_t * p_cur_req = NULL;
    lxzat_spcfg_t * p_cur_spcfg = NULL;
    lxzat_resp_calc_t * p_calc_resp = NULL;
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;

    if (p_lxzat_ctxt == NULL)
    {
        OS_DBG_LOG(("lxzat_plus_dccalc_resp,p_lxzat_ctxt is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    p_cur_req = p_lxzat_ctxt->pt_req_data;
    p_cur_spcfg = lxzat_spcomm_f_get(p_lxzat_ctxt->it_vsp_id);
    if ((p_cur_req == NULL) || (p_cur_spcfg == NULL))
    {
        OS_DBG_LOG(("lxzat_plus_dccalc_resp,p_cur_req or p_cur_spcfg is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    i_req_type = p_cur_req->it_req_type;
    switch (i_req_type)
    {
    case LXZAT_REQ_TYPE_SET:
        {
            p_calc_resp = p_lxzat_ctxt->pt_rsp_data;
            if (p_calc_resp != NULL)
            {
                lxzat_rsp_f_printf(p_lxzat_ctxt->it_vsp_id,
                    LXZAT_RSP_MODE_P1N0, 
                    "%s: %d,%d,%d",
                    p_lxzat_ctxt->pt_ai_cfg->pt_ai_keyword,
                    p_calc_resp->it_param1,
                    p_calc_resp->it_param2,
                    p_calc_resp->it_result);
            }
            break;
        }
        
    case LXZAT_REQ_TYPE_TEST:
        {
            lxzat_rsp_f_printf(p_lxzat_ctxt->it_vsp_id,
                LXZAT_RSP_MODE_P1N0, 
                "%s: (a,b)",
                p_lxzat_ctxt->pt_ai_cfg->pt_ai_keyword);
            break;
        }
    default:
        {
            e_err_code = E_LEC_ERR_UNSUPPORTED;
            break;
        }
    }
    
    return e_err_code;
}

/*
 *  Description:
 *    The reset handler of "AT+DCADD,AT+DCDEL,AT+DCMUL,AT+DCDIV".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dccalc_reset(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_ERR_MEM_NOT_ENOUGH;
    
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;
    lxzat_resp_calc_t * p_calc_resp = NULL;

    if (p_lxzat_ctxt != NULL)
    {
        p_calc_resp = p_lxzat_ctxt->pt_rsp_data;
        if (p_calc_resp != NULL)
        {
            free(p_calc_resp);
            p_calc_resp = NULL;

            e_err_code = E_LEC_OK;
        }
    }
    
    return e_err_code;
}

/*
 *  Description:
 *    The initialize handler of "AT+DCSTRADD".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dcstradd_init(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_OK;

    sint32 i_req_type = LXZAT_REQ_TYPE_ERR;
    lxzat_req_t * p_cur_req = NULL;
    lxzat_spcfg_t * p_cur_spcfg = NULL;
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;

    if (p_lxzat_ctxt == NULL)
    {
        OS_DBG_LOG(("lxzat_plus_dcstradd_init,p_lxzat_ctxt is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    p_cur_req = p_lxzat_ctxt->pt_req_data;
    p_cur_spcfg = lxzat_spcomm_f_get(p_lxzat_ctxt->it_vsp_id);
    if ((p_cur_req == NULL) || (p_cur_spcfg == NULL))
    {
        OS_DBG_LOG(("lxzat_plus_dcstradd_init,p_cur_req or p_cur_spcfg is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    i_req_type = p_cur_req->it_req_type;
    switch (i_req_type)
    {
    case LXZAT_REQ_TYPE_SET:
        {
            lxzat_resp_strcalc_t * p_strcalc_resp = NULL;

            sint32 i_len_param1 = 0;
            sint32 i_len_param2 = 0;
            sint32 i_len_result = 0;
            
            if (PARAM1_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_STRING)
            {
                return E_LEC_ERR_P_TYPE;
            }

            if (PARAM2_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_STRING)
            {
                return E_LEC_ERR_P_TYPE;
            }

            i_len_param1 = PARAM1(p_cur_req).pt_str->it_length;
            i_len_param2 = PARAM2(p_cur_req).pt_str->it_length;

            i_len_result = i_len_param1 + 1;
            if (i_len_param1 < i_len_param2 )
            {
                i_len_result = i_len_param2 + 1;
            }

            p_strcalc_resp = (lxzat_resp_strcalc_t *)malloc(sizeof(lxzat_resp_calc_t));
            if (p_strcalc_resp == NULL)
            {
                return E_LEC_ERR_MEM_NOT_ENOUGH;
            }

            memset(p_strcalc_resp, 0, sizeof(lxzat_resp_strcalc_t));
            p_strcalc_resp->pt_param1 = lxz_dstring_new(i_len_param1);
            if (p_strcalc_resp->pt_param1 == NULL)
            {
                free(p_strcalc_resp);
                return E_LEC_ERR_MEM_NOT_ENOUGH;
            }

            p_strcalc_resp->pt_param2 = lxz_dstring_new(i_len_param2);
            if (p_strcalc_resp->pt_param2 == NULL)
            {
                free(p_strcalc_resp->pt_param1);
                free(p_strcalc_resp);
                return E_LEC_ERR_MEM_NOT_ENOUGH;
            }

            p_strcalc_resp->pt_result = lxz_dstring_new(i_len_result);
            if (p_strcalc_resp->pt_result == NULL)
            {
                free(p_strcalc_resp->pt_param1);
                free(p_strcalc_resp->pt_param2);
                return E_LEC_ERR_MEM_NOT_ENOUGH;
            }

            lxz_dstring_copy(p_strcalc_resp->pt_param1, PARAM1(p_cur_req).pt_str);
            lxz_dstring_copy(p_strcalc_resp->pt_param2, PARAM2(p_cur_req).pt_str);
            p_lxzat_ctxt->pt_rsp_data = p_strcalc_resp;
            break;
        }
    case LXZAT_REQ_TYPE_TEST:
        {
            e_err_code = E_LEC_OK;
            break;
        }
    default:
        {
            e_err_code = E_LEC_ERR_UNSUPPORTED;
            break;
        }
    }
    return e_err_code;
}

/*
 *  Description:
 *    The request handler of "AT+DCSTRADD".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dcstradd_req(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_OK;

    sint32 i_req_type = LXZAT_REQ_TYPE_ERR;
    lxzat_req_t * p_cur_req = NULL;
    lxzat_spcfg_t * p_cur_spcfg = NULL;
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;

    if (p_lxzat_ctxt == NULL)
    {
        OS_DBG_LOG(("lxzat_plus_dcstradd_req,p_lxzat_ctxt is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    p_cur_req = p_lxzat_ctxt->pt_req_data;
    p_cur_spcfg = lxzat_spcomm_f_get(p_lxzat_ctxt->it_vsp_id);
    if ((p_cur_req == NULL) || (p_cur_spcfg == NULL))
    {
        OS_DBG_LOG(("lxzat_plus_dcstradd_req,p_cur_req or p_cur_spcfg is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    i_req_type = p_cur_req->it_req_type;
    switch (i_req_type)
    {
    case LXZAT_REQ_TYPE_SET:
        {
            lxzat_resp_strcalc_t * p_strcalc_resp = NULL;
            
            if (PARAM1_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_STRING)
            {
                return E_LEC_ERR_P_TYPE;
            }

            if (PARAM2_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_STRING)
            {
                return E_LEC_ERR_P_TYPE;
            }

            p_strcalc_resp = p_lxzat_ctxt->pt_rsp_data;


            lxz_dstring_copy(p_strcalc_resp->pt_result, p_strcalc_resp->pt_param2);
            break;
        }
    case LXZAT_REQ_TYPE_TEST:
        {
            e_err_code = E_LEC_OK;
            break;
        }
    default:
        {
            e_err_code = E_LEC_ERR_UNSUPPORTED;
            break;
        }
    }

    return e_err_code;
}

/*
 *  Description:
 *    The response handler of "AT+DCSTRADD".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dcstradd_resp(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_OK;

    sint32 i_req_type = LXZAT_REQ_TYPE_ERR;
    lxzat_req_t * p_cur_req = NULL;
    lxzat_spcfg_t * p_cur_spcfg = NULL;
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;

    if (p_lxzat_ctxt == NULL)
    {
        OS_DBG_LOG(("lxzat_plus_dcstradd_resp,p_lxzat_ctxt is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    p_cur_req = p_lxzat_ctxt->pt_req_data;
    p_cur_spcfg = lxzat_spcomm_f_get(p_lxzat_ctxt->it_vsp_id);
    if ((p_cur_req == NULL) || (p_cur_spcfg == NULL))
    {
        OS_DBG_LOG(("lxzat_plus_dcstradd_resp,p_cur_req or p_cur_spcfg is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    i_req_type = p_cur_req->it_req_type;
    switch (i_req_type)
    {
    case LXZAT_REQ_TYPE_SET:
        {
            lxzat_resp_strcalc_t * p_strcalc_resp = NULL;
            sint08 p_buf_result[127];
            
            p_strcalc_resp = p_lxzat_ctxt->pt_rsp_data;
            memset(p_buf_result, 0, sizeof(p_buf_result));
            lxz_dstring_get(p_strcalc_resp->pt_result, p_buf_result, sizeof(p_buf_result));
            lxzat_rsp_f_printf(p_lxzat_ctxt->it_vsp_id,
                LXZAT_RSP_MODE_P1N0, 
                "%s: %s", 
                p_lxzat_ctxt->pt_ai_cfg->pt_ai_keyword,
                p_buf_result);
            break;
        }
        
    case LXZAT_REQ_TYPE_TEST:
        {
            lxzat_rsp_f_printf(p_lxzat_ctxt->it_vsp_id,
                LXZAT_RSP_MODE_P1N0, 
                "%s: (\"a\",\"b\")", 
                p_lxzat_ctxt->pt_ai_cfg->pt_ai_keyword);
            break;
        }
    default:
        {
            e_err_code = E_LEC_ERR_UNSUPPORTED;
            break;
        }
    }
    
    return e_err_code;
}

/*
 *  Description:
 *    The reset handler of "AT+DCSTRADD".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dcstradd_reset(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_OK;
    
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;
    lxzat_resp_strcalc_t * p_strcalc_resp = NULL;

    if (p_lxzat_ctxt != NULL)
    {
        p_strcalc_resp = p_lxzat_ctxt->pt_rsp_data;
        if (p_strcalc_resp != NULL)
        {
            if (p_strcalc_resp->pt_param1)
            {
                free(p_strcalc_resp->pt_param1);
                p_strcalc_resp->pt_param1 = NULL;
            }
            if (p_strcalc_resp->pt_param2)
            {
                free(p_strcalc_resp->pt_param2);
                p_strcalc_resp->pt_param2 = NULL;
            }
            if (p_strcalc_resp->pt_result)
            {
                free(p_strcalc_resp->pt_result);
                p_strcalc_resp->pt_result = NULL;
            }
            free(p_strcalc_resp);
            p_strcalc_resp = NULL;

            e_err_code = E_LEC_OK;
        }
    }
    
    return e_err_code;
}

/*
 *  Description:
 *    The initialize handler of "AT+DCSTRDEL".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dcstrdel_init(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_OK;

    sint32 i_req_type = LXZAT_REQ_TYPE_ERR;
    lxzat_req_t * p_cur_req = NULL;
    lxzat_spcfg_t * p_cur_spcfg = NULL;
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;

    if (p_lxzat_ctxt == NULL)
    {
        OS_DBG_LOG(("lxzat_plus_dcstrdel_init,p_lxzat_ctxt is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    p_cur_req = p_lxzat_ctxt->pt_req_data;
    p_cur_spcfg = lxzat_spcomm_f_get(p_lxzat_ctxt->it_vsp_id);
    if ((p_cur_req == NULL) || (p_cur_spcfg == NULL))
    {
        OS_DBG_LOG(("lxzat_plus_dcstrdel_init,p_cur_req or p_cur_spcfg is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    i_req_type = p_cur_req->it_req_type;
    switch (i_req_type)
    {
    case LXZAT_REQ_TYPE_SET:
        {
            lxzat_resp_strcalc_t * p_strcalc_resp = NULL;

            sint32 i_len_param1 = 0;
            sint32 i_len_param2 = 0;
            sint32 i_len_result = 0;
            
            if (PARAM1_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_STRING)
            {
                return E_LEC_ERR_P_TYPE;
            }

            if (PARAM2_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_STRING)
            {
                return E_LEC_ERR_P_TYPE;
            }

            i_len_param1 = PARAM1(p_cur_req).pt_str->it_length;
            i_len_param2 = PARAM2(p_cur_req).pt_str->it_length;

            i_len_result = i_len_param1 + 1;
            if (i_len_param1 < i_len_param2 )
            {
                i_len_result = i_len_param2 + 1;
            }

            p_strcalc_resp = (lxzat_resp_strcalc_t *)malloc(sizeof(lxzat_resp_calc_t));
            if (p_strcalc_resp == NULL)
            {
                return E_LEC_ERR_MEM_NOT_ENOUGH;
            }

            memset(p_strcalc_resp, 0, sizeof(lxzat_resp_strcalc_t));
            p_strcalc_resp->pt_param1 = lxz_dstring_new(i_len_param1);
            if (p_strcalc_resp->pt_param1 == NULL)
            {
                free(p_strcalc_resp);
                return E_LEC_ERR_MEM_NOT_ENOUGH;
            }

            p_strcalc_resp->pt_param2 = lxz_dstring_new(i_len_param2);
            if (p_strcalc_resp->pt_param2 == NULL)
            {
                free(p_strcalc_resp->pt_param1);
                free(p_strcalc_resp);
                return E_LEC_ERR_MEM_NOT_ENOUGH;
            }

            p_strcalc_resp->pt_result = lxz_dstring_new(i_len_result);
            if (p_strcalc_resp->pt_result == NULL)
            {
                free(p_strcalc_resp->pt_param1);
                free(p_strcalc_resp->pt_param2);
                return E_LEC_ERR_MEM_NOT_ENOUGH;
            }

            lxz_dstring_copy(p_strcalc_resp->pt_param1, PARAM1(p_cur_req).pt_str);
            lxz_dstring_copy(p_strcalc_resp->pt_param2, PARAM2(p_cur_req).pt_str);
            p_lxzat_ctxt->pt_rsp_data = p_strcalc_resp;
            break;
        }
    case LXZAT_REQ_TYPE_TEST:
        {
            e_err_code = E_LEC_OK;
            break;
        }
    default:
        {
            e_err_code = E_LEC_ERR_UNSUPPORTED;
            break;
        }
    }
    return e_err_code;
}

/*
 *  Description:
 *    The request handler of "AT+DCSTRDEL".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dcstrdel_req(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_OK;

    sint32 i_req_type = LXZAT_REQ_TYPE_ERR;
    lxzat_req_t * p_cur_req = NULL;
    lxzat_spcfg_t * p_cur_spcfg = NULL;
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;

    if (p_lxzat_ctxt == NULL)
    {
        OS_DBG_LOG(("lxzat_plus_dcstrdel_req,p_lxzat_ctxt is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    p_cur_req = p_lxzat_ctxt->pt_req_data;
    p_cur_spcfg = lxzat_spcomm_f_get(p_lxzat_ctxt->it_vsp_id);
    if ((p_cur_req == NULL) || (p_cur_spcfg == NULL))
    {
        OS_DBG_LOG(("lxzat_plus_dcstrdel_req,p_cur_req or p_cur_spcfg is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    i_req_type = p_cur_req->it_req_type;
    switch (i_req_type)
    {
    case LXZAT_REQ_TYPE_SET:
        {
            lxzat_resp_strcalc_t * p_strcalc_resp = NULL;
            
            if (PARAM1_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_STRING)
            {
                return E_LEC_ERR_P_TYPE;
            }

            if (PARAM2_TYPE(p_cur_req) != LXZAT_PARAM_TYPE_STRING)
            {
                return E_LEC_ERR_P_TYPE;
            }

            p_strcalc_resp = p_lxzat_ctxt->pt_rsp_data;
            lxz_dstring_copy(p_strcalc_resp->pt_result, p_strcalc_resp->pt_param2);
            break;
        }
    case LXZAT_REQ_TYPE_TEST:
        {
            e_err_code = E_LEC_OK;
            break;
        }
    default:
        {
            e_err_code = E_LEC_ERR_UNSUPPORTED;
            break;
        }
    }

    return e_err_code;
}

/*
 *  Description:
 *    The response handler of "AT+DCSTRDEL".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dcstrdel_resp(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_OK;

    sint32 i_req_type = LXZAT_REQ_TYPE_ERR;
    lxzat_req_t * p_cur_req = NULL;
    lxzat_spcfg_t * p_cur_spcfg = NULL;
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;

    if (p_lxzat_ctxt == NULL)
    {
        OS_DBG_LOG(("lxzat_plus_dcstrdel_resp,p_lxzat_ctxt is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    p_cur_req = p_lxzat_ctxt->pt_req_data;
    p_cur_spcfg = lxzat_spcomm_f_get(p_lxzat_ctxt->it_vsp_id);
    if ((p_cur_req == NULL) || (p_cur_spcfg == NULL))
    {
        OS_DBG_LOG(("lxzat_plus_dcstrdel_resp,p_cur_req or p_cur_spcfg is NULL\r\n"));
        return E_LEC_ERR_UNKNOWN;
    }

    i_req_type = p_cur_req->it_req_type;
    switch (i_req_type)
    {
    case LXZAT_REQ_TYPE_SET:
        {
            lxzat_resp_strcalc_t * p_strcalc_resp = NULL;
            sint08 p_buf_result[127];
            
            p_strcalc_resp = p_lxzat_ctxt->pt_rsp_data;
            memset(p_buf_result, 0, sizeof(p_buf_result));
            lxz_dstring_get(p_strcalc_resp->pt_result, p_buf_result, sizeof(p_buf_result));
            lxzat_rsp_f_printf(p_lxzat_ctxt->it_vsp_id,
                LXZAT_RSP_MODE_P1N0, 
                "%s: %s", 
                p_lxzat_ctxt->pt_ai_cfg->pt_ai_keyword,
                p_buf_result);
            break;
        }
        
    case LXZAT_REQ_TYPE_TEST:
        {
            lxzat_rsp_f_printf(p_lxzat_ctxt->it_vsp_id,
                LXZAT_RSP_MODE_P1N0, 
                "%s: (\"a\",\"b\")", 
                p_lxzat_ctxt->pt_ai_cfg->pt_ai_keyword);
            break;
        }
    default:
        {
            e_err_code = E_LEC_ERR_UNSUPPORTED;
            break;
        }
    }
    
    return e_err_code;
}

/*
 *  Description:
 *    The reset handler of "AT+DCSTRDEL".
 *  Param: pctxt, the pointer of AT command context;
 *  Return: Operating results;
 *  Note: NONE
 */
static sint32 lxzat_plus_dcstrdel_reset(void * pctxt)
{
    LXZAT_ERROR_CODE_E e_err_code = E_LEC_OK;
    
    lxzat_context_t * p_lxzat_ctxt = (lxzat_context_t *)pctxt;
    lxzat_resp_strcalc_t * p_strcalc_resp = NULL;

    if (p_lxzat_ctxt != NULL)
    {
        p_strcalc_resp = p_lxzat_ctxt->pt_rsp_data;
        if (p_strcalc_resp != NULL)
        {
            if (p_strcalc_resp->pt_param1)
            {
                free(p_strcalc_resp->pt_param1);
                p_strcalc_resp->pt_param1 = NULL;
            }
            if (p_strcalc_resp->pt_param2)
            {
                free(p_strcalc_resp->pt_param2);
                p_strcalc_resp->pt_param2 = NULL;
            }
            if (p_strcalc_resp->pt_result)
            {
                free(p_strcalc_resp->pt_result);
                p_strcalc_resp->pt_result = NULL;
            }
            free(p_strcalc_resp);
            p_strcalc_resp = NULL;

            e_err_code = E_LEC_OK;
        }
    }
    
    return e_err_code;
}
